﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace UI.NetworkDiagram
{
    public class Vertice 
    {
        #region events
        public event OnVerticeSelected VerticeSelected;
        public event OnVerticeMoved VerticeMoved;
        #endregion

        #region props
        public int VerticeID { get; set; }
        public bool ConstrainedToCanvas { get; set; }
        public bool Selected { get; set; }
        public bool Highlighted { get; set; }
        public bool Disabled { get; set; }
        public Vector Position { get; set; }
        public Vector Force { get; set; }
        public Vector Velocity { get; set; }
        public bool CanMove { get; set; }
        public double Scale { get; set; }
        public string EntityType { get; set; }
        public int EntityID { get; set; }
        #endregion

        #region UI
        public Ellipse Ball { get; set; }
        public TextBlock Label { get; set; }
        public TextBlock TooltipBox { get; set; }
        #endregion

        #region ctor
        public Vertice(int verticeID, string label, string tooltip,
            double scale, string entityType, int entityID)
        {
            this.VerticeID = verticeID;
            this.Scale = scale;
            this.EntityType = entityType;
            this.EntityID = entityID;
            this.Ball=new Ellipse();
            double minSize = 25;
            double maxSize = 60;
            double ballSize = minSize + (maxSize - minSize) * scale;
            this.Ball.Width = this.Ball.Height = ballSize;
            Color centerColor = Color.FromArgb(255, 255, 200, 200);
            Color borderColor = Color.FromArgb(255, 255, 0, 0);
            this.Ball.Fill = new RadialGradientBrush(centerColor, borderColor);
            this.Ball.Stroke = new SolidColorBrush(borderColor);
            this.Label = new TextBlock();
            this.Label.Text = label;
            this.TooltipBox=new TextBlock();
            this.TooltipBox.Text = tooltip;
            ToolTipService.SetToolTip(this.Ball, this.TooltipBox);

            this.Position=new Vector();
            this.Force=new Vector();
            this.Velocity=new Vector();
            this.CanMove = true;
            this.ConstrainedToCanvas = true;
            this.Selected = false;
            this.Highlighted = false;
            this.Disabled = false;

            this.Ball.MouseLeftButtonDown += new MouseButtonEventHandler(Ball_MouseLeftButtonDown);
            this.Ball.MouseEnter += new MouseEventHandler(Ball_MouseEnter);
            this.Ball.MouseLeave += new MouseEventHandler(Ball_MouseLeave);
        }

        void Ball_MouseLeave(object sender, MouseEventArgs e)
        {
            if(this.Label.Visibility==Visibility.Visible)
            {
                this.Label.FontWeight = FontWeights.Normal;
            }
        }

        void Ball_MouseEnter(object sender, MouseEventArgs e)
        {
            if (this.Label.Visibility == Visibility.Visible)
            {
                this.Label.FontWeight = FontWeights.Bold;
            }
        }

        void Ball_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (this.VerticeSelected != null)
                this.VerticeSelected(this);
        }
        #endregion

        #region draw
        public void SnapVertice()
        {
            this.Ball.SetValue(Canvas.LeftProperty, this.Position.X - this.Ball.ActualWidth/2);
            this.Ball.SetValue(Canvas.TopProperty, this.Position.Y - this.Ball.ActualHeight/2);
            this.Ball.Arrange(new Rect(this.Position.ToPoint(), this.Ball.DesiredSize));
            this.Label.SetValue(Canvas.LeftProperty, Math.Max(0, this.Position.X - this.Label.ActualWidth/2));
            this.Label.SetValue(Canvas.TopProperty, Math.Max(0, this.Position.Y + this.Ball.ActualHeight/2+3));
        }

        public void MoveToPosition(Vector delta)
        {
            if(this.CanMove)
                this.Position += delta;
        }

        public void AddForce(Vector newForce)
        {
            this.Force += newForce;
        }

        public void ResetForce()
        {
            this.Force=new Vector();
        }

        public void SetPosition(Vector position, Rect constraintRectangle)
        {
            position.X = Math.Min(constraintRectangle.Right, Math.Max(constraintRectangle.Left, position.X));
            position.Y = Math.Min(constraintRectangle.Top, Math.Max(constraintRectangle.Top, position.Y));
            this.Position = position;
            if (this.VerticeMoved != null)
                this.VerticeMoved(this);
        }
        #endregion
    }
}
